﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace mqtttLib.Helper
{
    public static class MqttUtils
    {
        /// <summary>
        /// 把指定的二进制值显示为适合记入日志的文本串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string GetHexLog(this byte[] data)
        {
            if (data == null) return "";
            string result = "";
            int start = 0;
            while (start < data.Length)
            {
                if (!result.Equals("")) result += "\r\n";
                int len = data.Length - start;
                if (len > 16) len = 16;
                string strByte = BitConverter.ToString(data, start, len);
                strByte = strByte.Replace('-', ' ');
                if (len > 8)
                {
                    strByte = strByte.Substring(0, 23) + "-" + strByte.Substring(24);
                }
                if (len < 16)
                {
                    strByte += new string(' ', (16 - len) * 3);
                }
                strByte += "  ";
                for (int i = 0; i < len; i++)
                {
                    char c = Convert.ToChar(data[start + i]);
                    if (char.IsControl(c))
                    {
                        c = '.';
                    }
                    strByte += c;
                }
                result += strByte;
                start += len;
            }
            return result;
        }
        public static byte ToByte(this bool b)
        {
            switch (b)
            {
                case true:
                    return 1;
                default:
                    return 0;
            }
        }


        //public static void WriteShort(this List<byte> bytes, int value)
        //{
        //    bytes.Add((byte)(value >> 8));
        //    bytes.Add((byte)(value & 0xFF));
        //}


        /// <summary>
        /// 尾部添加
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="value"></param>
        public static void AddLast(this LinkedList<byte> bytes, short value)
        {
            bytes.AddLast((byte)(value >> 8));
            bytes.AddLast((byte)(value & 0xFF));
        }
        /// <summary>
        /// 头部添加
        /// </summary>
        /// <param name="result"></param>
        /// <param name="buffers"></param>
        public static void AddFirst(this LinkedList<byte> result, byte[] buffers)
        {
            for (int i = buffers.Length - 1; i >= 0; i--)
            {
                result.AddFirst(buffers[i]);
            }
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="result"></param>
        /// <param name="buffers"></param>
        public static void AddLast(this LinkedList<byte> result, byte[] buffers)
        {
            foreach (var item in buffers)
            {
                result.AddLast(item);
            }

        }
        /// <summary>
        ///    写入 MQTT字符串。
        /// </summary>
        /// <param name="buffers">字符串的流</param>
        /// <param name="value">要写入的字符串</param>
        public static void AddLast(this LinkedList<byte> buffers, string value)
        {
            lock (_objectlock)
            {
                System.Text.Encoding enc = new MqttEncoding();
                byte[] stringBytes = enc.GetBytes(value);
                foreach (var item in stringBytes)
                {
                    buffers.AddLast(item);
                }
            }
        }
        /// <summary>
        /// byte数组 复制
        /// </summary>
        /// <param name="buffers">源</param>
        /// <param name="arrayIndex">复制开始的位置</param>  
        /// <param name="length">长度</param>
        /// <returns></returns>
        public static byte[] CopyTo(this byte[] buffers, int arrayIndex, int length)
        {
            lock (_objectlock)
            {
                byte[] bodys = new byte[length];
                if (buffers.Length >= length)
                {
                    buffers.ToList().CopyTo(arrayIndex, bodys, 0, length);
                }
                return bodys;
            }
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="buffers"></param>
        /// <param name="offset">开始地址 偏移量</param>
        /// <param name="length">长度</param>
        /// <returns></returns>
        public static byte[] Read(this byte[] buffers, ref int offset, int length)
        {
            lock (_objectlock)
            {

                if (buffers.Length >= length)
                {
                    byte[] result = buffers.CopyTo(offset, length);
                    offset += length;
                    return result;
                }
                return new byte[length];
            }
        }

        private static object _objectlock = new object();
        /// <summary>
        /// 读取
        /// </summary>
        /// <param name="buffers"></param>
        /// <param name="offset">开始地址 偏移量</param>
        /// <returns></returns>
        public static string ReadString(this byte[] buffers, ref int offset)
        {
            lock (_objectlock)
            {
                if (buffers.Length < 2)
                {
                    return "";
                }
                // 读取长度
                var enc = new MqttEncoding();
                int temp = offset;
                ushort stringLength = (ushort)enc.GetCharCount(buffers.Read(ref offset, 2));

                if (stringLength > buffers.Length)
                {
                    string c = "";
                }
                // 从字符串中读取字节，验证我们已经足够了  
                byte[] stringBytes = buffers.Read(ref offset, stringLength);
                return enc.GetString(stringBytes);
            }

        }

        /// <summary>
        /// 读取
        /// </summary> 
        /// <param name="buffers"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static short ReadShort(this byte[] buffers, ref int offset)
        {
            lock (_objectlock)
            {
                var high = buffers[offset];
                offset++;
                var low = buffers[offset];
                offset++;
                return (short)((high << 8) + low);
            }
        }

        ///// <summary>
        ///// 读取
        ///// </summary> 
        ///// <param name="buffers"></param>
        ///// <returns></returns>
        //public static short ReadShort(this byte[] buffers)
        //{
        //    var high = buffers[0];
        //    var low = buffers[1];
        //    return (short)((high << 8) + low);
        //}



        ///// <summary>
        ///// 读取
        ///// </summary>
        ///// <param name="stream"></param>
        ///// <returns></returns>
        //public static short ReadShort(this Stream stream)
        //{
        //    byte high, low;
        //    high = (byte)stream.ReadByte();
        //    low = (byte)stream.ReadByte();
        //    return (short)((high << 8) + low);
        //}

    }
}
